#!/usr/bin/python

import os, re, subprocess
import shutil
from common import *
import config

def cleanup(streams, logname = None):
    for s in streams:
        streamdata = streams[s]
        if streamdata.has_key('fname'):
            map(removeFile, streamdata['fname'])
        if streamdata.has_key('IFO'):
            removeFile(streamdata['IFO'])
        if streamdata.has_key('idx'):
            removeFile(streamdata['idx'])
        if streamdata.has_key('sub'):
            removeFile(streamdata['sub'])
    if logname:
        removeFile(logname)

def getLogName(tsfile):
    return os.path.splitext(os.path.split(tsfile)[1])[0] + '_log.txt'

def getstreams(tsfile):
    output = subprocess.Popen([config.toolPaths['ffmpeg'], '-i', tsfile], stderr = subprocess.PIPE).communicate()[1]
    streams = {}
    program = None
    for line in output.splitlines():
        r = re.search('Program (\d+)', line)
        if r:
            program = r.group(1)

        r = re.search('Stream #.*?\[(.*?)\][(]?(.*?)[)]?: (.*?): (.*)', line)
        if r:
            pid, language, streamtype, details = r.groups()
            pxpid = "0x%.4X" % (int(r.group(1), 16))
            streams[pxpid] = {'type': streamtype, 'details': details}
            streams[pxpid]['program'] = program
            if language:
                streams[pxpid]['language'] = language

            programpid = '%s.%s' % (program, pid)
            if config.pidTeletextPageMap.has_key(programpid):
                streams[pxpid]['pages']= [{'teletextpage':config.pidTeletextPageMap[programpid],'language':language}]
                streams[pxpid]['type']='Teletext'
    return streams

def generateXini(fname, streams):
    f = open(fname, 'wt')
    f.write('''
# Project-X INI
# ProjectX 0.90.04.00.b32 / 31.10.2009

# SubtitlePanel
SubtitlePanel.SubpictureColorModel=%s
SubtitlePanel.exportTextAsUTF8=1
SubtitlePanel.exportTextAsUnicode=0
SubtitlePanel.SubtitleExportFormat=SRT
SubtitlePanel.SubtitleExportFormat_2=null
SubtitlePanel.exportAsVobSub=1
SubtitlePanel.rebuildPTS=1
'''%config.settings['subpicturecolormodel'])

    pages = []
    [pages for pages in [streams[stream]['pages'] for stream in streams if streams[stream].has_key('pages')]]
    teletextpages = [ page['teletextpage'] for page in pages ]
    for i in range(0, len(teletextpages)):
        f.write('SubtitlePanel.TtxPage%d=%s\n' % (i + 1, teletextpages[i]))

def resolvefilenames(streams, logfile):
    cont = open(logfile).read()
    pid = None
    for line in cont.splitlines():
        r = re.search('\+\+\> .*?: PID (\w+)', line)
        if r:
            pid = "0x%.4X" % (int(r.group(1), 16))
            print pid

        r = re.search('---> new File: (.*)', line)
        if r:
            fname = r.group(1).strip("'")
            print fname
            if streams[pid].has_key('fname'):
                if fname not in streams[pid]['fname']:
                    streams[pid]['fname'].append(fname)
            else:
                streams[pid]['fname'] = [fname]
            if fname.endswith('.sup'):
                if not fname + '.sub' in streams[pid]['fname']:
                    streams[pid]['fname'].append(fname + '.sub')
                if not fname + '.idx' in streams[pid]['fname']:
                    streams[pid]['fname'].append(fname + '.idx')
                if not fname + '.IFO' in streams[pid]['fname']:
                    streams[pid]['fname'].append(fname + '.IFO')
    return streams

def demux(tsfile, pids, xini = None):
    fname = tsfile
    def searchCutMarkers(fname):
        if os.path.exists(fname + '(0).Xcl'):
            return fname + '(0).Xcl'
        if os.path.exists(fname + '.Xcl'):
            return fname + '.Xcl'

    baseName = os.path.splitext(os.path.split(fname)[1])[0]
    logName = getLogName(tsfile)
    cutmarkers = searchCutMarkers(fname)
    print "fname =", fname
    print "logName =", logName
    print "cutmarkers =", cutmarkers
    print "demuxing..."
    projectXDir = config.settings['projectXDir']
    configDir = config.settings['configDir']
    if not xini:
        xini = os.path.join(configDir, 'X.ini')

    colourstableexists = os.path.exists(os.path.join(os.getcwd(), 'colours.tbl'))
    if not colourstableexists:
        shutil.copy(os.path.join(config.projectXDir, 'colours.tbl'), os.getcwd())
        logger = Logger()
        logger.log('cp %s .\n' % (os.path.join(projectXDir, 'colours.tbl')))

    if (cutmarkers == None):
        execute('java -jar "%s" -id %s -ini "%s" -demux "%s" -out .' % (os.path.join(projectXDir, 'ProjectX.jar'), ",".join(pids), xini, fname))
    else:
        execute('java -jar "%s" -id %s -ini "%s" -cut "%s" -demux "%s" -out .' % (os.path.join(projectXDir, 'ProjectX.jar'), ",".join(pids), xini, cutmarkers, fname))

    if not colourstableexists:
        os.remove('colours.tbl')
        logger.log('\nrm colours.tbl\n')

    print "done"

def getstreamsx(tsfile):
    projectXDir = config.settings['projectXDir']
    execute('java -jar "%s" -id 0 -log "%s" -out .' % (os.path.join(projectXDir, 'ProjectX.jar'), tsfile))
    return parsedemuxlog(getLogName(tsfile),tsfile)

def parsedemuxlog(logfile):
    return getstreamsfromdemuxlog(logfile, None)

def parsedemuxlog(logfile, tsfile):
    cont = open(logfile).read()

    streams = {}

    def parse_Video(sectioncont, streamtype):
        for pid in re.compile('PID: (\w+)[(]?#?', re.DOTALL + re.MULTILINE).findall(sectioncont):
            streams[pid] = {'type': streamtype}

    #Audio:
    #PID: 0x0C3C{swe}
    #PID: 0x0C3F{fin}
    #PID: 0x0C41(AC-3){eng}(AC-3)[PD]

    def parse_Audio(sectioncont, streamtype):
        for pid, language in re.compile('PID: (\w+)\S*{(\w+)}', re.DOTALL + re.MULTILINE).findall(sectioncont):
            streams[pid] = {'type': streamtype, 'language': language}

    #Viasat classic
    #Teletext:
    #PID: 0x0C40(swe_s690 nor_s691 dan_s692 fin_s694 )
    # Yle 2
    #Teletext:
    #PID: 0x1388(fin_i100 )(#10)

    def parse_Teletext(sectioncont, streamtype):
        #for pid, language in re.compile('PID: (\w+)[(]([a-z]+)', re.DOTALL + re.MULTILINE).findall(sectioncont):
        for pid, language in re.compile('PID: (\w+)[(](.*)\s\)', re.DOTALL + re.MULTILINE).findall(sectioncont):
            for lang in language.split(' '):
                page = lang.split('_')
                if len(page) == 2:
                    if len(page[1]) > 0 and page[1][0] == 's':
                        if streams.has_key(pid):
                            streams[pid]['pages'].append({'language': page[0],'teletextpage':page[1].strip('s')})
                        else:
                            streams[pid] = {'type': streamtype, 'pages': [{'language': page[0],'teletextpage':page[1].strip('s')}]}
                    elif len(page[1]) > 0 and page[1][0] == 'i':
                        if tsfile:
                            s = getstreams(tsfile)
                            if s.has_key(pid) and s[pid].has_key('pages'):
                                streams[pid] = s[pid]

    def parse_Subpict(sectioncont, streamtype):
        for pid, language in re.compile('PID: (\w+)(?:\(#\d\))?[(]([a-z]+)', re.DOTALL + re.MULTILINE).findall(sectioncont):
            streams[pid] = {'type': streamtype, 'language': language}

    m = re.compile("usable streams:\n(?:^(.*?))\n\n", re.DOTALL + re.MULTILINE).search(cont)
    if m:
        for section in re.findall('(.*?):\n', m.group(1)):
            m = re.compile('(?:%s:\n)(.*?)\n(?!PID)' % (section), re.DOTALL + re.MULTILINE).search(cont)
            if m:
                vars()['parse_' + filter(lambda x: x.isdigit() or x.isalpha(), section)](m.group(1), section)

    #for pid in streams:
    #    m = re.compile(": PID %s.+?(?:new File: '?(.+?)'?)?$\n\n" % (pid), re.DOTALL + re.MULTILINE).search(cont)
    #    if m:
    #        fname = m.group(1)
    #        if fname:
    #            streams[pid]['fname'] = fname
    #            if streams[pid]['type'] == 'Subpict.':
    #                streams[pid]['sub'] = fname + '.sub'
    #                streams[pid]['idx'] = fname + '.idx'
    #                streams[pid]['IFO'] = fname + '.IFO'

    return streams

if __name__ == '__main__':
    import sys

    tsfile = sys.argv[1]
    logName = getLogName(tsfile)

    #demux(tsfile)

    #print 'SUMMARY OF STREAMS:'
    streams = getstreams(tsfile)
    #print streams
    streams = resolvefilenames(streams, logName)
    for s in streams:
        print 'PID:', s, streams[s]


    #print 'teletext pages:', [streams[stream]['teletextpage'] for stream in streams if streams[stream].has_key('teletextpage')]
